package hsrt.com.dynamiccomponent_android.dynamic_component;

import android.util.Pair;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

public class LinkListHelper {

    /**
     * 通过链表来转化为数组,需要注意的是,这个方法会区分section,所以是在主体数据的时候使用.
     *
     * @param rootDataElement .
     * @return .
     */
    @SuppressWarnings("unchecked")
    public static ArrayList<DataElement> getListWithLinkList(DataElement rootDataElement) {
        //todo 先要获取多少个section,然后获取section变更后第一个元素,并把剩下的当前组的元素使用addsubitem来进行添加.
        ArrayList<DataElement> resultArrayList = new ArrayList<>();
        DataElement temp = rootDataElement;
        int lastSection = -1;
        DataElement lastDataElement = temp;
        while (temp != null) {
            int section = temp.getSection();
            if (section != lastSection) {
                lastDataElement = temp;
                lastSection = section;
                resultArrayList.add(temp);
            } else {
                lastDataElement.addSubItem(temp);
            }

            temp = (DataElement) temp.getNext();
        }
        return resultArrayList;
    }


    /**
     * 通过链表来转化为数组,这个方法是不需要进行section区分的,所以只是简单的生成数组.
     *
     * @param rootDataElement .
     * @return .
     */
    public static ArrayList<DataElement> getSimpleListWithLinkList(DataElement rootDataElement) {
        ArrayList<DataElement> resultArrayList = new ArrayList<>();
        DataElement temp = rootDataElement;
        while (temp != null) {
            resultArrayList.add(temp);
            temp = (DataElement) temp.getNext();
        }
        return resultArrayList;
    }

    public static DataElementInterface insertDataElement(final DataElementInterface dataElement, int position, final DataElementInterface
            rootDataElement) {

        if (position < 0 || dataElement == null || rootDataElement == null) {
            return rootDataElement;
        }
        DataElementInterface result = rootDataElement;

        DataElementInterface target = getTargetDataElement(rootDataElement, position);
        DataElementInterface last = getLastDataElement(dataElement);

        //todo 处理插入到0的时候的情况
        DataElementInterface previous;
        if (target.getPrevious() != null) {
            previous = (DataElementInterface) target.getPrevious().get();
            previous.setNext(dataElement);
            dataElement.setPrevious(new WeakReference<>(previous));
        } else {
            result = dataElement;
        }
        last.setNext(target);
        target.setPrevious(new WeakReference<>(last));

        return result;
    }

    /**
     * 根据position获取dataelement
     *
     * @param rootDataElement .
     * @param position        .
     * @return .
     */
    private static DataElementInterface getTargetDataElement(DataElementInterface rootDataElement, int position) {
        DataElementInterface temp = rootDataElement;
        while (temp != null) {
            if (position == 0) {
                break;
            }
            position--;
            temp = temp.getNext();
        }
        return temp;
    }

    /**
     * 获取当前链表的最后一个元素
     *
     * @param root .
     * @return .
     */
    private static DataElementInterface getLastDataElement(DataElementInterface root) {
        DataElementInterface temp = root;
        while (temp.getNext() != null) {
            temp = temp.getNext();
        }
        return temp;
    }

    /**
     * 根据flag来获取最后一个元素和元素数
     *
     * @param root .
     * @return .
     */
    private static Pair<DataElementInterface, Integer> getLastDataElementWithChildrenFlag(DataElementInterface root) {
        DataElementInterface temp = root;
        int count = 0;
        while (temp != null) {
            if (temp.getSection() != root.getSection() || temp.getChildObjectFlag() == null || !temp.getChildObjectFlag().equals(root
                    .getChildObjectFlag())) {
                count = Math.max(0, count - 1);
                if (temp.getPrevious() == null) {
                    break;
                }
                temp = (DataElementInterface) temp.getPrevious().get();
                break;
            }

            if (temp.getNext() == null) {
                break;
            }
            temp = temp.getNext();
            count++;
        }

        return new Pair<>(temp, count);
    }


    public static Pair<DataElementInterface, Integer> deleteChildObjectDataElement(DataElementInterface childRootDataElement, DataElementInterface
            root) {
        if (childRootDataElement == null) {
            return null;
        }

        DataElementInterface result = root;
        Pair<DataElementInterface, Integer> lastPair = getLastDataElementWithChildrenFlag(childRootDataElement);
        DataElementInterface last = lastPair.first;
        int count = lastPair.second;

        DataElementInterface previous = null;
        if (childRootDataElement.getPrevious() != null) {
            previous = (DataElementInterface) childRootDataElement.getPrevious().get();
            previous.setNext(last.getNext());
        } else {
            result = last.getNext();
        }

        last.getNext().setPrevious(new WeakReference<>(previous));
        last.setNext(null);

        return new Pair<>(result, count);
    }
}
